$include("js/mootools.js");
$include("js/dataGrid.css");

//数据格式
var DataType={};

//字符串类型
DataType['String']=
{
	set:function(td,value)
	{
		td.innerHTML=(value+"").htmlEncode();
	}
}

DataType['Number']=
{
	set:function(td,value)
	{
		td.style.textAlign='right';
		value=parseFloat(value);
		if(value<0)
			td.innerHTML="<font color=red>"+value+"</font>";
		else
			td.innerHTML=value;
	}
}

DataType['lineNumber']=
{
	set:function(td,value)
	{
		td.innerHTML=td.parentNode.rowIndex;
	}
}

DataType['Boolean']=
{
	set:function(td,value)
	{
		if(value+""=="true")
			td.innerHTML="<img src=\""+_contextPath+"/opesoft/images/y.png\">";
		else
			td.innerHTML="<img src=\""+_contextPath+"/opesoft/images/n.png\">";
	}
}

//数据表中的一列
function DataGridField(name,width,type,hidden)
{
	this.name=name;  //显示的文字
	this.width=width;  //初始化的宽度
	this.type=type;  //类型
	this.minWidth=10;  //最小的宽度
	this.hidden=(hidden==null)?false:hidden;  //是否隐藏
	
	this._dataGrid;  //所属的DataGrid对象
	this._headTh;  //表头的TH，用于固定宽度
	this._headTd;  //表头的TD，显示表头
	this._handleTd;  //表头控制区的TD
	this._bodyTh;  //数据表的TH
	this._mouseup;  //用于临时保存body的mouseUp事件
	this._mousemove;  //用于临时保存body的mouseMove事件
	this._x=-1;  //用于计算Mouse偏移量的临时变量
	//this._hidden=false;  //是否显示
	//if(this.type<0) this._hidden=true;

	var self=this;

	this.mouseDownOnHandle=function(event)
	{
		if(self._mouseup==null)
		{
			self._mouseup=document.body.onmouseup;
			document.body.onmouseup=self.mouseUpOnHandle;
		}

		if(self._mousemove==null)
		{
			self._mousemove=document.body.onmousemove;
			document.body.onmousemove=self.mouseMoveOnHandle;
		}

		var event = new Event(event); 
		self._x=event.page.x;
	}

	this.mouseUpOnHandle=function(event)
	{
		self._x=-1;
		document.body.onmouseup=self._mouseup;
		self._mouseup=null;
		document.body.onmousemove=self._mousemove;
		self._mousemove=null;
	}

	this.mouseMoveOnHandle=function(event)
	{
		if(self._x>-1)
		{
			var event = new Event(event); 
			var w=event.page.x-self._x;  //计算横向移动的距离
			self._x=event.page.x;

			self.addWidth(w);
		}		
	}
}

//改变列的尺寸
DataGridField.prototype.addWidth=function(size)
{
	var width=this.getWidth()+size;  //计算出实际的宽度
	if(width>=this.minWidth)
	{
		var tableWidth=this._dataGrid.getWidth()+size;  //计算表格的总宽度

		this._dataGrid._headTable.width=tableWidth;  //修改Head的总宽度
		this._headTh.width=width-this._dataGrid.handleSize;  //修改当前Head单元格的宽度
		this._dataGrid._bodyTable.width=tableWidth;  //修改Body的总宽度
		this._bodyTh.width=width;  //修改Body单元格的宽度
		this._dataGrid.obj.style.width=tableWidth+this._dataGrid.scrollWidth;  //修改显示区域DIV的宽度
		this._dataGrid._footTable.width=tableWidth;  //修改底部表格的宽度
	}
}

//设置列的尺寸
DataGridField.prototype.setWidth=function(width)
{
	this.addWidth(width-this.getWidth());
}

//取得列的尺寸
DataGridField.prototype.getWidth=function()
{
	return this._bodyTh==null?0:parseInt(this._bodyTh.width);
}

function DataGrid(id)
{
	this.id=id;  //显示表格DIV的ID
	this.obj=$(id);  //显示表格DIV对象
	if(this.obj==null) { alert("Can't find DIV : "+this.id); }
	this.fields=new Array();  //表头数组
	this.data;  //存放表格数据的二维数组
	this.multiSelect=true;  //是否可以多选
	this.selectedRows=new Array();  //被选择的行
	this.selectedEvent=null;  //当选择行后触发的事件，传入的参数为：(DataGrid,发生事件的行,是否是选择事件(也可能是取消选择事件))

	this._headTable;  //表头的表格
	this._bodyTable;  //显示数据的表格
	this._footTable;  //底部的表格

	this.handleSize=8;  //表头上控制区域的宽度，不能太小，因为FF下要有一个空格
	this.scrollWidth=20;  //数据表右边为滚动条留出的宽度

	this._x=-1;  //用于计算横向偏移量
	this._y=-1;  //用于计算纵向偏移量
	this._mousemove;  //用于临时保存事件的变量
	this._mouseup;  //用于临时保存事件的变量
	this._dragState;  //当Mouse在表格上拖拽时，对多选的情况进行判断

	var self=this;

	this.mouseDownOnFoot=function(event)
	{
		if(self._mouseup==null)
		{
			self._mouseup=document.body.onmouseup;
			document.body.onmouseup=self.mouseUpOnFoot;
		}

		if(self._mousemove==null)
		{
			self._mousemove=document.body.onmousemove;
			document.body.onmousemove=self.mouseMoveOnFoot;
		}

		self.obj.style.borderWidth=1;
	}

	this.mouseDownOnFoot1=function(event)
	{
		self.mouseDownOnFoot()

		var event=new Event(event); 
		self._y=event.page.y;
	}

	this.mouseDownOnFoot2=function(event)
	{
		self.mouseDownOnFoot();

		var event=new Event(event);
		self._x=event.page.x;
		self._y=event.page.y;

		self.obj.style.overflowX='scroll';
	}

	this.mouseUpOnFoot=function(event)
	{
		self._x=-1;
		self._y=-1;

		document.body.onmouseup=self._mouseup;
		self._mouseup=null;
		document.body.onmousemove=self._mousemove;
		self._mousemove=null;

		var _w=parseInt(self.obj.style.width)-self.scrollWidth;
		if(_w!=self.getWidth()) self.setWidth(_w);

		self.obj.style.borderWidth=0;
		self.obj.style.overflowX='';
	}

	this.mouseMoveOnFoot=function(event)
	{
		var event = new Event(event);

		if(self._x>-1)
		{
			var w=event.page.x-self._x;
			self._x=event.page.x;

			self.obj.style.width=parseInt(self.obj.style.width)+w;
		}

		if(self._y>-1)
		{
			var h=event.page.y-self._y;
			self._y=event.page.y;

			self.setHeight(self.getHeight()+h);
		}
	}

	this.clickOnBody=function(event)
	{
		var index=this.rowIndex;  //取得发生事件的行
		self.changeSelectedState(index);
	}

	this.mouseDownOnBody=function(event)
	{
		var index=this.rowIndex;
		self._dragState=index;
	}

	this.mouseUpOnBody=function(event)
	{
		var index=this.rowIndex;

		//如果按下Mouse和放开不是在同一行，认为发生了拖动
		if(self._dragState!=null && self._dragState!=index)
		{
			var step=self._dragState<index?1:-1;
			for(var i=self._dragState;i!=index+step;i+=step)
			{
				self.changeSelectedState(i);
			}
		}
		
		self._dragState=null;
	}
}

//初始化并显示整个数据表
DataGrid.prototype.init=function(height)
{
	height=height==null?120:height;
	this._initHead();
	this._initBody();
	this._initFoot();

	this.obj.style.overflowY='scroll';
	this.obj.style.border='0px dashed #F00';
	this.obj.style.height=height;
	this.obj.style.width=parseInt(this._bodyTable.width)+this.scrollWidth;
}

//重新加载数据
DataGrid.prototype.reload=function()
{
	this._recordWidth();  //记录当前宽度
	if(this._bodyTable!=null)
		this._bodyTable.parentNode.removeChild(this._bodyTable);  //删除当前数据部分
	this._initBody();  //重新生成数据表

	this.selectedRows=new Array();  //要清空选择列表
	if(this.selectedEvent!=null)
		this.selectedEvent(this,null,false);
}

//把当前表格的实际宽度记录到Field.width属性中
DataGrid.prototype._recordWidth=function()
{
	for(var i=0;i<this.fields.length;i++)
	{
		this.fields[i].width=this.fields[i].getWidth();
	}
}

DataGrid.prototype._initHead=function()
{
	//生成表头
	var table=document.createElement('TABLE');
	table.className="dataGridHead";
	table.id=this.id+'$head';
	this._headTable=table;
	
	//加入表头的TH，用于固定宽度
	var headTableWidth=0;  //表格的总宽度
	var tr=table.insertRow(-1);
	for(var i=0;i<this.fields.length;i++)
	{
		var th=document.createElement("TH");
		tr.appendChild(th);
		th.width=this.fields[i].width-this.handleSize;
		this.fields[i]._headTh=th;

		if(this.fields[i].hidden) th.style.display='none';
		else headTableWidth+=parseInt(th.width);  //计算总宽度

		th=document.createElement("TH");
		tr.appendChild(th);
		th.width=this.handleSize;

		if(this.fields[i].hidden) th.style.display='none';
		else headTableWidth+=this.handleSize;  //计算总宽度
	}

	if($_.IE) tr.style.display='none';  //控制宽度的列不用于显示(FF下显示才能控制)
	table.width=headTableWidth;  //根据表头的TH，设置表格的总宽度
	$debug("Head table width : "+table.width);
	
	//加入表头
	tr=table.insertRow(-1);
	for(var i=0;i<this.fields.length;i++)
	{
		var td=tr.insertCell(-1);
		td.innerHTML=this.fields[i].name;
		td.alt=this.fields[i].name;
		td.title=this.fields[i].name;
		this.fields[i]._headTd=td;
		if(this.fields[i].hidden) td.style.display='none';

		td=tr.insertCell(-1);
		td.className='handle';
		if(!$_.IE) td.innerHTML="&nbsp;";
		this.fields[i]._handleTd=td;
		if(this.fields[i].hidden) td.style.display='none';

		this.fields[i]._dataGrid=this;
		td.onmousedown=this.fields[i].mouseDownOnHandle;
	}

	this.obj.parentNode.insertBefore(table,this.obj);  //在页面上显示表头
}

DataGrid.prototype._initBody=function()
{
	if(this.data==null || this.data.length<1)
		this.obj.innerHTML="<center>No Data!</center>";
	else
		this.obj.innerHTML="";  //清空显示数据表格DIV中的内容

	//生成数据表
	var table=document.createElement('TABLE');
	table.className="dataGrid";
	table.id=this.id+'$body';
	this._bodyTable=table;

	var bodyTableWidth=0;  //表格的总宽度
	var tr=table.insertRow(-1);
	for(var i=0;i<this.fields.length;i++)
	{
		var th=document.createElement("TH");
		tr.appendChild(th);
		th.width=this.fields[i].width;
		this.fields[i]._bodyTh=th;
		
		if(this.fields[i].hidden) th.style.display='none';
		else bodyTableWidth+=this.fields[i].width;  //计算总宽度
	}
	
	if($_.IE) tr.style.display='none';  //控制宽度的列不用于显示(FF下显示才能控制)
	table.width=bodyTableWidth;  //设置表格总宽度
	$debug("Body table width : "+table.width);

	if(this.data!=null)
	{
		for(var i=0;i<this.data.length;i++)
		{
			var tr=table.insertRow(-1);
			for(var j=0;j<this.fields.length;j++)
			{
				var td=tr.insertCell(-1);

				//显示数据
				if(this.fields[j].type!=null)
					this.fields[j].type.set(td,this.data[i][j]);
				else
					DataType.String.set(td,this.data[i][j]);  //默认以字符串方式处理

				//显示提示
				td.alt=this.data[i][j];
				td.title=td.alt;
				
				if(this.fields[j].hidden) td.style.display='none';
			}
			tr.className="line"+i%2;
			tr.onclick=this.clickOnBody;  //为数据行增加事件
			tr.onmousedown=this.mouseDownOnBody;
			tr.onmouseup=this.mouseUpOnBody;
		}
	}

	this.obj.appendChild(table);
}

DataGrid.prototype._initFoot=function()
{
	var table=document.createElement('TABLE');
	table.className="dataGridFoot";
	table.id=this.id+'$foot';
	table.width=parseInt(this._bodyTable.width);
	
	var tr=table.insertRow(-1);
	var td=tr.insertCell(-1);
	td.width='90%';
	td.style.cursor='s-resize';
	td.onmousedown=this.mouseDownOnFoot1;

	td=tr.insertCell(-1);
	td.width='10%';
	td.style.cursor='se-resize';
	td.onmousedown=this.mouseDownOnFoot2;

	this._footTable=table;

	//在页面上显示状态栏
	//this.obj.insertAdjacentElement('afterEnd',table);  
	document.body.appendChild(table);
	$(this.id+'$foot').injectAfter(this.id);
}

DataGrid.prototype.appendField=function(field)
{
	this.fields.push(field);
}

DataGrid.prototype.getWidth=function()
{
	return parseInt(this._bodyTable.width);
}

DataGrid.prototype.getHeight=function()
{
	return parseInt(this.obj.style.height);
}

DataGrid.prototype.setHeight=function(height)
{
	if(height>0) this.obj.style.height=height;
}

DataGrid.prototype.setWidth=function(width)
{
	var oldWidth=this.getWidth();
	var newWidth=0;
	var minWidth=0;
	var offset=0;  //因为有最小宽度限制，需要有这样一个值来弥补不足的宽度
	
	for(var i=0;i<this.fields.length;i++)
	{
		if(this.fields[i].hidden) continue;  //不计算隐藏列
		minWidth+=this.fields[i].minWidth;
		var w=Math.round(this.fields[i].getWidth()/oldWidth*width);
		if(w<this.fields[i].minWidth) offset+=this.fields[i].minWidth-w;
	}

	$debug("offset : "+offset);

	if(offset>0) width-=offset;
	if(width<0) width=0;

	$debug("width : "+width);

	for(var i=0;i<this.fields.length;i++)
	{
		if(this.fields[i].hidden) continue;  //不计算隐藏列
		var w=Math.round(this.fields[i].getWidth()/oldWidth*width);
		w=w<this.fields[i].minWidth?this.fields[i].minWidth:w;
		this.fields[i].setWidth(w);
	}
}

//取得指定行列的元素对象
DataGrid.prototype.getElement=function(rowIndex,cellIndex)
{
	return this._bodyTable.rows[rowIndex].cells[cellIndex];
}

//取得指定行列的值
DataGrid.prototype.getValue=function(rowIndex,cellIndex)
{
	return this.data[rowIndex-1][cellIndex];
}

//选择一行
DataGrid.prototype.selectLine=function(index)
{
	if(index>0 && index<this._bodyTable.rows.length)  //不处理表头
	{
		this._bodyTable.rows[index].className="selected";
		this.selectedRows.push(index);

		//回调选择事件
		if(this.selectedEvent!=null)
			this.selectedEvent(this,index,true);
	}
}

DataGrid.prototype.releaseLine=function(index)
{
	if(index>0 && index<this._bodyTable.rows.length)  //不处理表头
	{
		this.selectedRows.remove(index);
		this._bodyTable.rows[index].className='line'+(index+1)%2;

		//回调选择事件
		if(this.selectedEvent!=null)
			this.selectedEvent(this,index,false);
	}
}

//改变一行的选择状态
DataGrid.prototype.changeSelectedState=function(index)
{
	if(this.isSelected(index))
		this.releaseLine(index);
	else
		this.selectLine(index);
}

//返回指定行是否被选择
DataGrid.prototype.isSelected=function(index)
{
	return this.selectedRows.contains(index);
}
